﻿using AutoMapper;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using WMS.FC.Domain.DataTransferObject.Cell;
using WMS.FC.Domain.DomainObject.System;
using WMS.FC.Domain.PersistenceObject.Business;
using WMS.FC.Domain.PersistenceObject.History;
using WMS.FC.Domain.Repository;
using WMS.FC.Domain.Service.Cell.Interface;
using WMS.FC.Domain.Service.System;
using WMS.FC.Domain.Service.Technology.Interface;
using WMS.FC.Domain.Service.Tray.Interface;

namespace WMS.FC.Domain.Service.Cell
{
    public class BindCellService : ServiceBase, IBindCellService
    {
        protected readonly IAddTrayService addTrayService;
        protected readonly IAddCellService addCellService;
        protected readonly ITrayRepository trayRepository;
        protected readonly ICellRepository cellRepository;
        protected readonly ISplitTableRepository splitTableRepository;
        protected readonly IChangeTrayTechnologyService changeTrayTechnologyService;

        public BindCellService(
            ILogger<ServiceBase> logger,
            IOptions<WmsSettings> options,
            IMapper mapper,
            IAddTrayService addTrayService,
            ITrayRepository trayRepository,
            IAddCellService addCellService,
            ICellRepository cellRepository,
            IChangeTrayTechnologyService changeTrayTechnologyService,
            ISplitTableRepository splitTableRepository)
            : base(logger, options, mapper)
        {
            this.addTrayService = addTrayService;
            this.trayRepository = trayRepository;
            this.addCellService = addCellService;
            this.cellRepository = cellRepository;
            this.changeTrayTechnologyService = changeTrayTechnologyService;
            this.splitTableRepository = splitTableRepository;
        }

        public async Task<ActionResultBase> BindCell(string? trayBarcode, List<CellDTO>? cellList, string? stationCode, UserInfo userInfo)
        {
            var result = new ActionResultBase("绑定电池");
            try
            {
                if (string.IsNullOrWhiteSpace(trayBarcode))
                    return result.ArgumentError("托盘条码不能为空");

                if (cellList == null || cellList.Count == 0)
                    return result.ArgumentError("电池信息不能为空");

                if (cellList.GroupBy(cell => cell.CellBarcode).Any(group => !group.Key.StartsWith(options.Value.FakeCellBarcodePrefix, StringComparison.InvariantCultureIgnoreCase) && group.Count() > 1))
                    return result.ArgumentError("请求电池存在重复条码");

                if (cellList.GroupBy(cell => cell.CellPosition).Any(group => group.Count() > 1))
                    return result.ArgumentError("请求电池存在重复电池位置");

                var addTrayResult = await addTrayService.AddTray(trayBarcode, userInfo);
                if (!addTrayResult.IsSuccess)
                    return result.Fail(addTrayResult);

                var trayPO = addTrayResult.Data!;
                var trayCellList = await trayRepository.GetTrayCellList(trayBarcode);
                var cellPOList = new List<CellPO>();
                var hisBindCellPOList = new List<HisCellBindPO>();
                var count = 0;
                foreach (var cell in cellList)
                {
                    if (cell.CellBarcode.StartsWith(options.Value.FakeCellBarcodePrefix, StringComparison.InvariantCultureIgnoreCase))
                    {
                        var trayCell = trayCellList.FirstOrDefault((trayCell) => trayCell.CellPosition == cell.CellPosition);
                        if (trayCell == null)
                        {
                            count = await cellRepository.BindeFakeCell(trayBarcode, cell.CellPosition, userInfo);
                            if (count == 0)
                                return result.DbError($"托盘:({trayBarcode}),电池位置:({cell.CellPosition}),绑定假电池异常");
                        }
                        else if (!trayCell.Barcode.StartsWith(options.Value.FakeCellBarcodePrefix, StringComparison.InvariantCultureIgnoreCase))
                        {
                            if (trayCell != null)
                                return result.BusinessError($"托盘:({trayBarcode}),电池位置:({cell.CellPosition}),已经存在电池:({trayCell.Barcode}),不能组盘");
                        }
                    }
                    else
                    {
                        var addCellResult = await addCellService.AddCell(cell.CellBarcode, userInfo);
                        if (!addCellResult.IsSuccess)
                            return result.Fail(addCellResult);

                        var cellPO = addCellResult.Data!;
                        var trayCell = trayCellList.FirstOrDefault((trayCell) => trayCell.CellPosition == cell.CellPosition && trayCell.Barcode != cell.CellBarcode);
                        if (trayCell != null)
                            return result.BusinessError($"托盘:({trayBarcode}),电池位置:({cell.CellPosition}),已经存在电池:({trayCell.Barcode}),不能组盘");

                        cellPO.TrayBarcode = trayBarcode;
                        cellPO.CellPosition = cell.CellPosition;
                        cellPOList.Add(cellPO);

                        hisBindCellPOList.Add(new HisCellBindPO()
                        {
                            TypeCode = "BindType_Bind",
                            TrayBarcode = trayPO.Barcode,
                            CellPosition = cell.CellPosition,
                            CellBarcode = cell.CellBarcode,
                            StationCdoe = stationCode,
                            MaterialCode = cellPO.MaterialCode,
                            TechnologyRouteCode = cellPO.TechnologyRouteCode,
                            TechnologyProcessCode = cellPO.TechnologyProcessCode,
                            IsRework = cellPO.IsRework,
                            NgCode = cellPO.NgCode,
                            RankValue = cellPO.RankValue,
                        });
                    }
                }

                count = await cellRepository.Update(cellPOList, userInfo);
                if (count != cellPOList.Count)
                    return result.DbError("更新电池信息异常");

                count = await splitTableRepository.InsertSplitTable(hisBindCellPOList, userInfo);
                if (count == 0)
                    return result.DbError("新增电池绑盘履历异常");

                if (trayPO.TechnologyRouteCode != options.Value.EmptyTrayTechnologyRoute)
                {
                    var changeTrayTechnologyResult = await changeTrayTechnologyService.ChangeTrayTechnology(trayBarcode, trayPO.TechnologyRouteCode, trayPO.TechnologyProcessCode, userInfo);
                    if (!changeTrayTechnologyResult.IsSuccess)
                        return result.Fail(changeTrayTechnologyResult);
                }
                else
                {
                    var cellPO = cellPOList.FirstOrDefault(entity => entity.TechnologyRouteCode != options.Value.EmptyTrayTechnologyRoute);
                    if (cellPO != null)
                    {
                        var changeTrayTechnologyResult = await changeTrayTechnologyService.ChangeTrayTechnology(trayBarcode, cellPO.TechnologyRouteCode, cellPO.TechnologyProcessCode, userInfo);
                        if (!changeTrayTechnologyResult.IsSuccess)
                            return result.Fail(changeTrayTechnologyResult);
                    }
                }

                result.Message = "电池绑盘成功";
            }
            catch (Exception ex)
            {
                return result.Exception(ex);
            }

            return result;
        }

        public async Task<ActionResult<TrayPO>> BindCell(string? trayBarcode, List<CellDTO>? cellList, string? technologyRouteCode, string? technologyProcessCode, string? stationCode, UserInfo userInfo)
        {
            var result = new ActionResult<TrayPO>("绑定电池");
            try
            {
                if (string.IsNullOrWhiteSpace(trayBarcode))
                    return result.ArgumentError("托盘条码不能为空");

                if (string.IsNullOrWhiteSpace(technologyRouteCode))
                    return result.ArgumentError("工艺路径不能为空");

                if (string.IsNullOrWhiteSpace(technologyProcessCode))
                    return result.ArgumentError("工艺工序不能为空");

                if (cellList == null || cellList.Count == 0)
                    return result.ArgumentError("电池信息不能为空");

                if (cellList.GroupBy(cell => cell.CellBarcode).Any(group => !group.Key.StartsWith(options.Value.FakeCellBarcodePrefix, StringComparison.InvariantCultureIgnoreCase) && group.Count() > 1))
                    return result.ArgumentError("请求电池存在重复条码");

                if (cellList.GroupBy(cell => cell.CellPosition).Any(group => group.Count() > 1))
                    return result.ArgumentError("请求电池存在重复电池位置");

                var addTrayResult = await addTrayService.AddTray(trayBarcode, userInfo);
                if (!addTrayResult.IsSuccess)
                    return result.Fail(addTrayResult);

                var trayPO = addTrayResult.Data!;
                var count = await trayRepository.GetCount<CellPO>(entity => entity.TrayBarcode == trayBarcode);
                if (count > 0)
                {
                    count = await cellRepository.UnbindTray(trayBarcode, userInfo);
                }

                var cellPOList = new List<CellPO>();
                var hisBindCellPOList = new List<HisCellBindPO>();
                foreach (var cell in cellList)
                {
                    var addCellResult = await addCellService.AddCell(cell.CellBarcode, userInfo);
                    if (!addCellResult.IsSuccess)
                        return result.Fail(addCellResult);

                    var cellPO = addCellResult.Data!;
                    cellPO.TrayBarcode = trayBarcode;
                    cellPO.CellPosition = cell.CellPosition;
                    cellPOList.Add(cellPO);

                    hisBindCellPOList.Add(new HisCellBindPO()
                    {
                        TypeCode = "BindType_Bind",
                        TrayBarcode = trayPO.Barcode,
                        CellPosition = cell.CellPosition,
                        CellBarcode = cell.CellBarcode,
                        StationCdoe = stationCode,
                        MaterialCode = cellPO.MaterialCode,
                        TechnologyRouteCode = cellPO.TechnologyRouteCode,
                        TechnologyProcessCode = cellPO.TechnologyProcessCode,
                        IsRework = cellPO.IsRework,
                        NgCode = cellPO.NgCode,
                        RankValue = cellPO.RankValue,
                    });
                }

                count = await cellRepository.Update(cellPOList, userInfo);
                if (count != cellPOList.Count)
                    return result.DbError("更新电池信息异常");

                count = await splitTableRepository.InsertSplitTable(hisBindCellPOList, userInfo);
                if (count == 0)
                    return result.DbError("新增电池绑盘履历异常");

                var changeTrayTechnologyResult = await changeTrayTechnologyService.ChangeTrayTechnology(trayBarcode, technologyRouteCode, technologyProcessCode, userInfo);
                if (!changeTrayTechnologyResult.IsSuccess)
                    return result.Fail(changeTrayTechnologyResult);

                result.Message = "电池绑盘成功";
                result.Data = trayPO;
            }
            catch (Exception ex)
            {
                return result.Exception(ex);
            }

            return result;
        }
    }
}
